package service.rocksea.com.serviceapp;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * Created by 吴志华 on 2017/10/18.
 *
 */

public class UDPPacket
{
    public static final byte Unknown = 0x00;

    public static final byte JS_Login = (byte) 0x80;
    public static final byte JS_LoginResponse = (byte) 0x90;

    public static final byte REQUEST_PLAN = (byte)0x81;
    public static final byte REQUEST_PLAN_RESPONE = (byte)0x82;
    public static final byte PLAN_FILE = (byte)0x92;
    public static final byte PLAN_FILE_RESPONE = (byte)0x93;

    //nDataSize+22
    private byte  cFrameHead = (byte)0xAB;           // 帧头 0xAB
    public byte  cCommand = (byte) Unknown;         // 命令字
    private byte  machineID[] = new byte[16];        // 机器编号
    private short nDataSize = 0;                     // 数据长度,0-512
    public byte[]  DataArray = null;                // 数据，数据长度为0 时，本数据段为空
    private byte  cCheckSum = 0;                     // 校验和
    private byte  cFrameTail = (byte)0xAB;           // 帧尾 0xAB
    private static final String MACHINE_ID = "APP_SERVICE";
    public UDPPacket()
    {
        cFrameHead = (byte) 0xAB;
        cFrameTail = (byte) 0xAB;
        cCommand = Unknown;
        nDataSize = 0;
        DataArray = null;
        cCheckSum = 0;
        Arrays.fill(machineID, (byte)0);
    }
    public UDPPacket creatJSLogin()
    {
        cCommand = JS_Login;
        try
        {
            byte[] machineArray = MACHINE_ID.getBytes("GB2312");
            System.arraycopy(machineArray,0,machineID,0,machineArray.length);
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        nDataSize = 0X00;
        cCheckSum = 0;
        cCheckSum = checkSum();
        return this;
    }
    public byte[] getBytes()
    {
        byte[] bytes = new byte[nDataSize+22];

        bytes[0] = cFrameHead;
        bytes[1] = cCommand;
        System.arraycopy(machineID, 0, bytes, 2, 16);
        bytes[18] = (byte)(nDataSize&0xFF);
        bytes[19] = (byte)(nDataSize>>8&0xFF);
        if( nDataSize>0 )
        {
            System.arraycopy(DataArray, 0, bytes, 20, nDataSize);
        }
        bytes[20+nDataSize] = cCheckSum;
        bytes[21+nDataSize] = cFrameTail;
        return bytes;
    }
    //计算该包的校验和,(低位在前，高位在后)
    public byte checkSum()
    {
        byte cksum = 0;
        cksum += cFrameHead;
        cksum += cCommand;
        for (int i=0; i<16; i++)
        {
            cksum += machineID[i];
        }
        cksum += nDataSize&0xFF;
        cksum += nDataSize>>8&0xFF;
        if (nDataSize>0 && DataArray!=null)
        {
            for (int i=0; i<nDataSize; i++)
                cksum += DataArray[i];
        }
        cksum += cCheckSum;
        cksum += cFrameTail;
        cksum = (byte)((short)0x0100-cksum);
        return cksum;
    }

    public UDPPacket creatFilePacket(byte[] packet)
    {
        cCommand = PLAN_FILE;
        try
        {
            byte[] machineArray = MACHINE_ID.getBytes("GB2312");
            System.arraycopy(machineArray,0,machineID,0,machineArray.length);
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        nDataSize = (short) packet.length;
        DataArray = packet;
        cCheckSum = 0;
        cCheckSum = checkSum();
        return this;
    }

    public UDPPacket initWithBytes(final byte bytes[],final int len,int start) {
        cFrameHead = bytes[start++];
        cCommand = bytes[start++];
        System.arraycopy(bytes, start, machineID, 0, 16);
        start += 16;
        nDataSize = (short) (  (0x000FF & bytes[start]) | ((0x00FF & bytes[start+1])<<8) );
        start += 2;
        if( nDataSize>0 )
        {
            DataArray = new byte[nDataSize];
            System.arraycopy(bytes, start, DataArray, 0, nDataSize);
            start += nDataSize;
        }
        else
            DataArray = null;
        cCheckSum = bytes[start++];
        cFrameTail = bytes[start++];
        return this;
    }

    public UDPPacket creatPlanPacket(byte[] bytes)
    {
        cCommand = PLAN_FILE;
        try
        {
            byte[] machineArray = MACHINE_ID.getBytes("GB2312");
            System.arraycopy(machineArray,0,machineID,0,machineArray.length);
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        nDataSize = (short) bytes.length;
        DataArray = bytes;
        cCheckSum = 0;
        cCheckSum = checkSum();
        return this;
    }

    public byte[] bytes()
    {
        byte[] bytes = new byte[nDataSize+22];

        bytes[0] = cFrameHead;
        bytes[1] = cCommand;
        System.arraycopy(machineID, 0, bytes, 2, 16);

        bytes[18] = (byte)(nDataSize&0xFF);
        bytes[19] = (byte)(nDataSize>>8&0xFF);
        if( nDataSize>0 )
        {
            System.arraycopy(DataArray, 0, bytes, 20, nDataSize);
        }
        bytes[20+nDataSize] = cCheckSum;
        bytes[21+nDataSize] = cFrameTail;
        return bytes;
    }

    public String getMachineID()
    {
        if (machineID.length==0)
            return null;
        try
        {
            return new String(machineID,"GB2312");
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public int length() {
        return nDataSize+22;
    }
}
